package com.demo.common.dynamic.datasource.aop;

import com.demo.common.dynamic.datasource.annotation.DsSwitcher;
import com.demo.common.dynamic.datasource.utils.DsContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Objects;

/**
 * 数据源切换切面类
 *
 * @author molong
 * @date 2021/10/22
 */
@Component
@Aspect
@Slf4j
public class DsSwitcherAspect {

    /**
     * 切点
     */
    @Pointcut("@annotation(com.demo.common.dynamic.datasource.annotation.DsSwitcher)")
    private void dataSourcePointCut() {}

    /**
     * 在调用前切换数据源
     */
    @Before("dataSourcePointCut()")
    public void transServiceMethod(JoinPoint joinPoint) {
        //根据注解改变数据源
        MethodSignature signature =(MethodSignature) joinPoint.getSignature();
        Method method=signature.getMethod();

        DsSwitcher dsSwitcher =method.getAnnotation(DsSwitcher.class);
        if (Objects.nonNull(dsSwitcher)) {
            //获取参数值
            Object[] args = joinPoint.getArgs();
            //取第一个参数字段值,组装数据源唯一标识
            if(Objects.nonNull(args[0])){
                String dataSourceKey= args[0].toString();
                //取第一个参数字段值,数据源唯一标识
                DsContextHolder.setCurrentDataSourceKey(dataSourceKey);
                log.debug("切换数据源【"+dataSourceKey+"】");
            }
        }
    }

    /**
     * 在调用后（包括有异常的情况下），清空数据源标识
     */
    @After("dataSourcePointCut()")
    public void clearDs(JoinPoint joinPoint) {
        //在每次调用之后，清空数据源
        MethodSignature signature =(MethodSignature) joinPoint.getSignature();
        DsSwitcher dsSwitcher =signature.getMethod().getAnnotation(DsSwitcher.class);
        if (Objects.nonNull(dsSwitcher)) {
            log.debug("清空当前数据源标识【"+DsContextHolder.getCurrentDataSourceKey()+"】");
            DsContextHolder.clearDataSourceKey();
        }
    }

}
